﻿using Core.STL;
using UnityEngine;

namespace Core.RVO
{
    public class AgentSystem : Core.Component, IAwake
    {
        private static int sTotalID = 0;

        private readonly KeyList<int, Agent> agents = new();

        public IReadOnlyKeyList<int, Agent> GetAll() => agents;

        public int Count => agents.Count;

        public float DefaultNeighborDis;
        public int DefaultMaxNeighbors;
        public float DefaultTimeHorizon;
        public float DefaultTimeHorizonObst;
        public float DefaultRadius;
        public float DefaultMaxSpeed;
        public Vector2 DefaultVelocity;

        public void Awake()
        {

        }

        public override void Dispose()
        {
            if (IsDisposed) return;
            agents.Clear();
            base.Dispose();
        }

        public Agent GetByKey(int agent_no)
        {
            return agents.GetByKey(agent_no);
        }

        public Agent GetByIndex(int index)
        {
            return agents.GetByIndex(index);
        }

        public int Add(Vector2 position)
        {
            return Add(position, DefaultNeighborDis, DefaultMaxNeighbors,
                DefaultTimeHorizon, DefaultTimeHorizonObst,
                DefaultRadius, DefaultMaxSpeed, DefaultVelocity);
        }

        public int Add(Vector2 position, float neighbor_dist, int max_neighbors,
            float time_horizon, float time_horizon_obst, float radius,
            float max_speed, Vector2 velocity)
        {
            Agent agent = Entity.Create<Agent>();
            agent.SetData(sTotalID++, position, neighbor_dist, max_neighbors, time_horizon, time_horizon_obst, radius, max_speed, velocity);
            agents.Add(agent.Id, agent);
            return agent.Id;
        }

        public void Delete(int agent_no)
        {
            agents.Remove(agent_no);
        }
    }
}
